package com.alinesno.cloud.common.web.login.shiro;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import com.alinesno.cloud.base.boot.entity.ManagerAccountEntity;
import com.alinesno.cloud.base.boot.service.IManagerAccountService;
import com.alinesno.cloud.common.core.context.ApplicationContextProvider;
import com.alinesno.cloud.common.web.base.utils.ManagerSettingsUtils;
import com.alinesno.cloud.common.web.login.constants.LoginConstants;
import com.alinesno.cloud.common.web.login.token.LoginAccountToken;

/**
 * 用户认证信息
 * 
 * @author WeiXiaoJin
 * @sine 2019年4月5日 上午10:55:44
 */
@Component
public class AccountRealm extends AuthorizingRealm {

	private static final Logger log = LoggerFactory.getLogger(AccountRealm.class);

	@Autowired
	private ManagerSettingsUtils managerSettingsUtils ; 

	@Value("${alinesno.page.captcha:alinesno}")
	private String testPageCaptcha ; 
	
	private CredentialsMatcher credentialsMatcher ; 
	
	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		this.credentialsMatcher = credentialsMatcher ; 
	}

	@Override
	public CredentialsMatcher getCredentialsMatcher() {
		return credentialsMatcher ; 
	}

	/**
	 * 获取授权信息
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
	
		String username = (String) principals.getPrimaryPrincipal();

		log.debug("[{}]权限认证.", username);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//		Subject subject = SecurityUtils.getSubject();
//		ManagerAccountEntity dto = (ManagerAccountEntity) subject.getSession().getAttribute(LoginConstants.CURRENT_USER);
//		
//		Set<String> roles = managerAccountService.findRoles(dto);
//		Set<String> menus = managerAccountService.findPermissions(dto) ; 
//      
//		// 添加用户权限_仿shiro
//		dto.setRole(roles);
//		dto.setPermission(menus) ; 
	
		return info;
	}

	/**
	 * 登录认证
	 */
	@DependsOn("ManagerAccountService")
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
			throws AuthenticationException {
		LoginAccountToken token = (LoginAccountToken) authenticationToken;
		log.debug("[{}]身份认证方法.", ToStringBuilder.reflectionToString(token));
		
		log.debug("credentialsMatcher:{}" , credentialsMatcher);

		// 从数据库获取对应用户名密码的用户
		ManagerAccountEntity dto = ApplicationContextProvider.getBean(IManagerAccountService.class).findByLoginName(token.getUsername());
		log.debug("maanger account dto: {}", ToStringBuilder.reflectionToString(dto));
		
		// 验证码
		validateCaptcha(token) ;

		if (null == dto) {
			throw new UnknownAccountException("用户名不正确");
		} 
//		else if (!dto.getPassword().equals(new String((char[]) token.getCredentials()))) {
//			throw new IncorrectCredentialsException("密码不正确");
//		}

		String password = dto.getPassword();
		return new SimpleAuthenticationInfo(token.getPrincipal(), password, getName());
	}

	/**
	 * 验证码校验
	 * 
	 * @return
	 */
	private boolean validateCaptcha(LoginAccountToken token) {

		boolean b = managerSettingsUtils.isOpenCaptcha(); // 验证是否需要打开
		if (b) {
			Object captcha = SecurityUtils.getSubject().getSession().getAttribute(LoginConstants.VERIFY_CODE_ACTUAL) ;
			String pageCaptcha = token.getCaptcha();
		
			if(StringUtils.isNotBlank(testPageCaptcha) && testPageCaptcha.equals(pageCaptcha)) {  // 存在万能验证码
				return true ; 
			}
			
			if (captcha == null || pageCaptcha == null || StringUtils.isBlank(pageCaptcha)) {
				throw new IncorrectCredentialsException("验证码为空.");
			} 
			
			if(captcha.equals(pageCaptcha)) {
				return true ; 
			}else {
				throw new IncorrectCredentialsException("验证码不正确");
			}
			
		} 

		return true ;
	}

}
